#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
MCP Calculator Server - Deployment and Management Script

升级版MCP计算器服务器部署和管理脚本
"""

import os
import sys
import json
import shutil
import subprocess
import argparse
from pathlib import Path
from typing import Dict, Any, Optional

class DeploymentManager:
    """部署管理器"""
    
    def __init__(self, project_root: Path):
        self.project_root = project_root
        self.src_dir = project_root / "src"
        self.logs_dir = project_root / "logs"
        self.data_dir = project_root / "data"
        self.config_file = project_root / "config_enhanced.json"
        self.env_file = project_root / ".env"
        
    def check_requirements(self) -> bool:
        """检查系统要求"""
        print("🔍 检查系统要求...")
        
        # 检查Python版本
        if sys.version_info < (3, 8):
            print("❌ 错误: 需要Python 3.8或更高版本")
            print(f"   当前版本: {sys.version}")
            return False
        print(f"✅ Python版本: {sys.version.split()[0]}")
        
        # 检查必要的目录
        required_dirs = [self.src_dir]
        for dir_path in required_dirs:
            if not dir_path.exists():
                print(f"❌ 错误: 缺少必要目录 {dir_path}")
                return False
        print("✅ 目录结构完整")
        
        # 检查核心文件
        required_files = [
            self.src_dir / "main_enhanced.py",
            self.src_dir / "calculator_engine.py",
            self.src_dir / "config.py",
            self.project_root / "requirements_enhanced.txt"
        ]
        
        for file_path in required_files:
            if not file_path.exists():
                print(f"❌ 错误: 缺少必要文件 {file_path}")
                return False
        print("✅ 核心文件完整")
        
        return True
    
    def install_dependencies(self, force: bool = False) -> bool:
        """安装依赖"""
        print("📦 安装依赖包...")
        
        requirements_file = self.project_root / "requirements_enhanced.txt"
        if not requirements_file.exists():
            print(f"❌ 错误: 找不到依赖文件 {requirements_file}")
            return False
        
        try:
            cmd = [sys.executable, "-m", "pip", "install", "-r", str(requirements_file)]
            if force:
                cmd.append("--force-reinstall")
            
            result = subprocess.run(cmd, capture_output=True, text=True)
            
            if result.returncode == 0:
                print("✅ 依赖安装成功")
                return True
            else:
                print(f"❌ 依赖安装失败: {result.stderr}")
                return False
                
        except Exception as e:
            print(f"❌ 安装依赖时出错: {e}")
            return False
    
    def setup_directories(self) -> bool:
        """设置目录结构"""
        print("📁 设置目录结构...")
        
        try:
            # 创建必要的目录
            directories = [self.logs_dir, self.data_dir]
            
            for dir_path in directories:
                dir_path.mkdir(exist_ok=True)
                print(f"✅ 创建目录: {dir_path}")
            
            return True
            
        except Exception as e:
            print(f"❌ 设置目录失败: {e}")
            return False
    
    def setup_configuration(self) -> bool:
        """设置配置文件"""
        print("⚙️ 设置配置文件...")
        
        try:
            # 检查配置文件
            if not self.config_file.exists():
                print(f"❌ 错误: 找不到配置文件 {self.config_file}")
                return False
            
            # 设置环境变量文件
            env_example = self.project_root / ".env.example"
            if env_example.exists() and not self.env_file.exists():
                shutil.copy2(env_example, self.env_file)
                print(f"✅ 创建环境配置文件: {self.env_file}")
                print("   请根据需要编辑 .env 文件")
            
            # 验证配置文件格式
            with open(self.config_file, 'r', encoding='utf-8') as f:
                config_data = json.load(f)
            
            if 'calculator-server-enhanced' in config_data:
                print("✅ 配置文件格式正确")
                return True
            else:
                print("❌ 错误: 配置文件格式不正确")
                return False
                
        except Exception as e:
            print(f"❌ 设置配置失败: {e}")
            return False
    
    def run_tests(self) -> bool:
        """运行测试"""
        print("🧪 运行测试套件...")
        
        test_file = self.project_root / "test_enhanced_server.py"
        if not test_file.exists():
            print(f"⚠️ 警告: 找不到测试文件 {test_file}")
            return True  # 不强制要求测试
        
        try:
            result = subprocess.run(
                [sys.executable, str(test_file)],
                cwd=str(self.project_root),
                capture_output=True,
                text=True
            )
            
            print(result.stdout)
            if result.stderr:
                print(result.stderr)
            
            if result.returncode == 0:
                print("✅ 所有测试通过")
                return True
            else:
                print("⚠️ 部分测试失败，但部署可以继续")
                return True  # 测试失败不阻止部署
                
        except Exception as e:
            print(f"⚠️ 运行测试时出错: {e}")
            return True  # 测试错误不阻止部署
    
    def generate_startup_script(self) -> bool:
        """生成启动脚本"""
        print("🚀 生成启动脚本...")
        
        try:
            # Windows批处理脚本
            bat_script = self.project_root / "start_server.bat"
            bat_content = f"""@echo off
echo Starting Enhanced MCP Calculator Server...
cd /d "{self.project_root}"
python "{self.src_dir / 'main_enhanced.py'}"
pause
"""
            
            with open(bat_script, 'w', encoding='utf-8') as f:
                f.write(bat_content)
            print(f"✅ 创建Windows启动脚本: {bat_script}")
            
            # PowerShell脚本
            ps1_script = self.project_root / "start_server.ps1"
            ps1_content = f"""# Enhanced MCP Calculator Server Startup Script
Write-Host "Starting Enhanced MCP Calculator Server..." -ForegroundColor Green
Set-Location "{self.project_root}"
python "{self.src_dir / 'main_enhanced.py'}"
"""
            
            with open(ps1_script, 'w', encoding='utf-8') as f:
                f.write(ps1_content)
            print(f"✅ 创建PowerShell启动脚本: {ps1_script}")
            
            # Python启动脚本
            py_script = self.project_root / "start_server.py"
            py_content = f"""#!/usr/bin/env python3
# -*- coding: utf-8 -*-
\"\"\"Enhanced MCP Calculator Server Startup Script\"\"\"

import sys
import os
from pathlib import Path

# 添加项目根目录到Python路径
project_root = Path(__file__).parent
sys.path.insert(0, str(project_root))

# 设置工作目录
os.chdir(project_root)

if __name__ == "__main__":
    try:
        from src.main_enhanced import main
        main()
    except KeyboardInterrupt:
        print("\\n服务器已停止")
    except Exception as e:
        print(f"启动失败: {{e}}")
        sys.exit(1)
"""
            
            with open(py_script, 'w', encoding='utf-8') as f:
                f.write(py_content)
            print(f"✅ 创建Python启动脚本: {py_script}")
            
            return True
            
        except Exception as e:
            print(f"❌ 生成启动脚本失败: {e}")
            return False
    
    def deploy(self, skip_tests: bool = False, force_deps: bool = False) -> bool:
        """执行完整部署"""
        print("🚀 开始部署Enhanced MCP Calculator Server")
        print("=" * 60)
        
        steps = [
            ("检查系统要求", lambda: self.check_requirements()),
            ("设置目录结构", lambda: self.setup_directories()),
            ("安装依赖包", lambda: self.install_dependencies(force_deps)),
            ("设置配置文件", lambda: self.setup_configuration()),
            ("生成启动脚本", lambda: self.generate_startup_script()),
        ]
        
        if not skip_tests:
            steps.append(("运行测试套件", lambda: self.run_tests()))
        
        for step_name, step_func in steps:
            print(f"\n📋 {step_name}...")
            if not step_func():
                print(f"❌ 部署失败: {step_name}")
                return False
        
        print("\n" + "=" * 60)
        print("🎉 部署成功完成！")
        print("\n📋 下一步操作:")
        print("1. 检查并编辑 .env 文件（如需要）")
        print("2. 更新 config_enhanced.json 中的路径")
        print("3. 在Claude Desktop中配置MCP服务器")
        print("4. 运行 start_server.py 或 start_server.bat 启动服务器")
        print("\n📖 详细说明请参考 README_Enhanced.md")
        
        return True
    
    def status(self) -> Dict[str, Any]:
        """检查部署状态"""
        status_info = {
            'project_root': str(self.project_root),
            'directories': {},
            'files': {},
            'configuration': {},
            'dependencies': {}
        }
        
        # 检查目录
        directories = {
            'src': self.src_dir,
            'logs': self.logs_dir,
            'data': self.data_dir
        }
        
        for name, path in directories.items():
            status_info['directories'][name] = {
                'path': str(path),
                'exists': path.exists(),
                'is_dir': path.is_dir() if path.exists() else False
            }
        
        # 检查文件
        files = {
            'main_enhanced': self.src_dir / 'main_enhanced.py',
            'config_enhanced': self.config_file,
            'env_file': self.env_file,
            'requirements': self.project_root / 'requirements_enhanced.txt'
        }
        
        for name, path in files.items():
            status_info['files'][name] = {
                'path': str(path),
                'exists': path.exists(),
                'size': path.stat().st_size if path.exists() else 0
            }
        
        # 检查配置
        try:
            if self.config_file.exists():
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    config_data = json.load(f)
                status_info['configuration']['valid'] = 'calculator-server-enhanced' in config_data
            else:
                status_info['configuration']['valid'] = False
        except Exception:
            status_info['configuration']['valid'] = False
        
        return status_info
    
    def cleanup(self) -> bool:
        """清理部署文件"""
        print("🧹 清理部署文件...")
        
        try:
            cleanup_items = [
                self.logs_dir,
                self.data_dir / "calculator_history.db",
                self.project_root / "start_server.bat",
                self.project_root / "start_server.ps1",
                self.project_root / "start_server.py",
                self.project_root / "enhanced_test_report.json"
            ]
            
            for item in cleanup_items:
                if item.exists():
                    if item.is_dir():
                        shutil.rmtree(item)
                        print(f"✅ 删除目录: {item}")
                    else:
                        item.unlink()
                        print(f"✅ 删除文件: {item}")
            
            print("✅ 清理完成")
            return True
            
        except Exception as e:
            print(f"❌ 清理失败: {e}")
            return False

def main():
    """主函数"""
    parser = argparse.ArgumentParser(
        description="Enhanced MCP Calculator Server 部署和管理工具",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
示例用法:
  python deploy.py deploy              # 完整部署
  python deploy.py deploy --skip-tests # 跳过测试的部署
  python deploy.py status              # 检查部署状态
  python deploy.py cleanup             # 清理部署文件
"""
    )
    
    subparsers = parser.add_subparsers(dest='command', help='可用命令')
    
    # 部署命令
    deploy_parser = subparsers.add_parser('deploy', help='部署服务器')
    deploy_parser.add_argument('--skip-tests', action='store_true', help='跳过测试')
    deploy_parser.add_argument('--force-deps', action='store_true', help='强制重新安装依赖')
    
    # 状态命令
    subparsers.add_parser('status', help='检查部署状态')
    
    # 清理命令
    subparsers.add_parser('cleanup', help='清理部署文件')
    
    args = parser.parse_args()
    
    if not args.command:
        parser.print_help()
        return
    
    # 获取项目根目录
    project_root = Path(__file__).parent
    manager = DeploymentManager(project_root)
    
    if args.command == 'deploy':
        success = manager.deploy(
            skip_tests=args.skip_tests,
            force_deps=args.force_deps
        )
        sys.exit(0 if success else 1)
        
    elif args.command == 'status':
        status_info = manager.status()
        print(json.dumps(status_info, indent=2, ensure_ascii=False))
        
    elif args.command == 'cleanup':
        success = manager.cleanup()
        sys.exit(0 if success else 1)

if __name__ == "__main__":
    main()